aws-vaultでcliとterraformをいい感じにしてみる
はじめに
データアナリティクス事業本部のkobayashiです。
最近入社以来使用していた愛機のMacBookProの入れ替えを行いました。開発環境の引っ越しは中々面倒ですがいい機会なので冗長になっていた設定だったりセキュアでない設定を見直すことにしました。その中でawsへの認証情報を管理してくれているツールでaws-vaultがありますが、この度aws-vaultの設定を見直したところ非常に使い勝手が良くなったのでまとめます。
aws-vaultとは
aws cliやプログラムからAWSの認証情報を使う際にはaws configure
を実行し、アクセスキーとシークレットキーを入力して~/.aws/credentials
にそれらの値を平文で保存して使うことになります。平文で保存されているので、~/.aws/credentials
を見れば簡単にアクセスキーとシークレットキーを見ることができてしまいます。そこでaws-vaultを使うことでアクセスキーとシークレットキーをOSのキーストアに保存し、認証情報が必要な場面において一時的な認証情報を取得してaws cliやプログラムから使うことができます。
詳しくは当ブログに導入から丁寧に説明してある記事がありますのでそちらをご一読ください。
AWS CLIをaws-vaultの認証情報で実行する
AWS CLIでサポートされているcredential_process
では外部プロセスから資格情報を取得しAWS CLIの実行時に使うことができます。
今回行ってみるのはこのcredential_process
を使用して外部プロセスとしてaws-vaultから直接認証情報を取得することにより
aws-vault exec myrole1 -- aws sts get-caller-identity
のようにaws-vault exec
の引数でaws
コマンドを指定するのではなく
aws sts get-caller-identity --profile myrole1
のような形でAWS CLIのコマンドをそのまま使った形で実行することができるように設定します。
- 外部プロセスを使用して認証情報を作成する - AWS Command Line Interface
- aws-vault/USAGE.md at master · 99designs/aws-vault · GitHub
またMFAが設定されたスイッチ元のアカウントから複数のAWSアカウントへのスイッチロールを行う場合、通常それぞれのAWSアカウントごとにMFAコードの入力が必要になります。しかし、aws-vault
のセッションキャッシュ機能を利用することで、stsのセッションが切れるまでMFAコードを一度だけ入力すればよくなります。
まとめると以下を行うことが目的です。
credential_process
を使ってaws-vault exec myrole1 -- aws sts get-caller-identity
ではなくaws sts --profile myrole1 get-caller-identity
で実行できるようにする- stsのセッションが切れるまではスイッチロールしても初回だけしかMFAコードを聞かれないようにする
環境
- aws-vault: v7.2.0
- aws-cli: 2.12.3
設定
では早速設定を行っていきますが、当ブログエントリのAWS Vaultで端末内のAWSアクセスキー平文保存をやめてみた | DevelopersIO の下記設定をもとにして設定を変更していきます。
$ cat ~/.aws/config [profile classmethod] [profile common] source_profile = classmethod region=ap-northeast-1 output=json mfa_serial=arn:aws:iam::123456789012:mfa/<IAMユーザ名> role_session_name=<IAMユーザ名> [profile myrole1] include_profile=common role_arn=arn:aws:iam::999999999999:role/<ロール名> [profile myrole2] include_profile=common role_arn=arn:aws:iam::888888888888:role/<ロール名>
この設定はaws-vault
にclassmethod
というプロファイル名でアクセスキーとシークレットキーを登録し、スイッチ元の設定をcommon
プロファイルに設定した上でスイッチ先をmyrole1
、myrole2
として呼び出す設定でした。
この設定を以下のように変更します。
- スイッチ元のプロファイル設定をアクセスキーとシークレットキーを登録してある
classmethod
に設定する common
プロファイルにcredential_process
を追加してaws-vaultの認証情報を受け取る--duration 12h
でセッションの継続時間を最大の12時間に設定
- スイッチ元のプロファイルの
include_profile
をsource_profile
に変更するinclude_profile
はaws-vault
独自の値なのでrole_session_name
,region
,output
をそれぞれのプロファイルに設定する
設定変更後は下記の内容になります。
[profile classmethod] mfa_serial=arn:aws:iam::123456789012:mfa/<IAMユーザ名> region=ap-northeast-1 output=json [profile common] credential_process=aws-vault --prompt terminal export classmethod --duration 12h --format=json [profile myrole1] source_profile=common role_arn=arn:aws:iam::999999999999:role/<ロール名> role_session_name=<ロールセッション名> region=ap-northeast-1 output=json [profile myrole2] source_profile=common role_arn=arn:aws:iam::888888888888:role/<ロール名> role_session_name=<ロールセッション名> region=ap-northeast-1 output=json
これで設定は終わりなので実際のコマンドを使って試してみます。
直接AWSコマンドを実行してみる
はじめにmyrole1
にAWSコマンドを実行してみますが念のためaws-vault clear
でセッションをクリアしておきます。
$aws-vault clear
myrole1
にAWSコマンドを実行してみるとMFAコードを聞かれ、入力すると以下のようにロールの一時的な認証情報を利用してコマンドを実行することができます。
$aws --profile myrole1 sts get-caller-identity Enter MFA code for arn:aws:iam::123456789012:mfa/<IAMユーザ名>: 123456 { "UserId": "AROA2YA6CJSXXXXXXXXXX:<ロールセッション名>", "Account": "999999999999", "Arn": "arn:aws:sts::999999999999:assumed-role/<ロール名>/<ロールセッション名>" }
次にmyrole2
にAWSコマンドを実行してみると今度はMFAコードを聞かれずロールの一時的な認証情報を利用してコマンドを実行することができます。
$aws --profile myrole2 sts get-caller-identity { "UserId": "AROATCX6VEHXXXXXXXXXX:<ロールセッション名>", "Account": "888888888888", "Arn": "arn:aws:sts::888888888888:assumed-role/<ロール名>/<ロールセッション名>" }
このようにAWSコマンドを直接利用できるのとMFA資格情報をキャッシュできるようになったことがわかります。
またaws-vault
コマンドを使ってAWSコマンドを実行することもできます。
$aws-vault exec myrole1 -- aws sts get-caller-identity { "UserId": "AROA2YA6CJSXXXXXXXXXX:<ロールセッション名>", "Account": "999999999999", "Arn": "arn:aws:sts::999999999999:assumed-role/<ロール名>/<ロールセッション名>" } $aws-vault exec myrole2 -- aws sts get-caller-identity { "UserId": "AROATCX6VEHXXXXXXXXXX:<ロールセッション名>", "Account": "888888888888", "Arn": "arn:aws:sts::888888888888:assumed-role/<ロール名>/<ロールセッション名>" }
そのため引き続きaws-vaultをTerraformで使うこともできます。
$aws-vault exec myrole1 -- terraform init
まとめ
aws-vaultの設定を見直して、AWSコマンドを直接使えるようにしつつMFAのセッション情報を共通のプロファイルでキャッシュできるようにしてみました。これによりaws-vault exex プロファイル名 -- aws
のような形ではなくaws --profile プロファイル名
の形でAWSコマンドを使用できるようになり、また一度MFAコードを入力すればセッションが切れるまでは別のプロファイルでもMFAコードを入力する必要がなくなりました。
最後まで読んで頂いてありがとうございました。